/*
 * Copyright (C) 2021 HiHope Open Source Organization .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 *
 * limitations under the License.
 */

#include "aht20.h"

#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_i2c.h"
#include "iot_gpio.h"


#include "hi_wifi_api.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"


#include "ssd1306.h"
#include "ssd1306_tests.h"

#define STACK_SIZE     (4096)
#define I2C_DATA_RATE  (400 * 1000)  // 400K
#define DELAY_S        (1)
#define     PWM_DUTY_50            (50)
#define     PWM_FREQ_4K            (4000)


#define Beep_IOT_PWM_PORT_PWM0   0
#define Beep_GPIO_IDX_9          9
#define Beep_GPIO_PWM_FUNCTION   5

#define IOT_PWM_PORT_PWM_MAX    4
#define IOT_PWM_DUTY_MAX        100
#define PWM_FREQ_DIVITION       64000
#define CLK_160M                160000000
#define DELAY_300MS            (300 * 1000)
#define NUM_2                   2

#define RED_LED_PIN_NAME        10
#define GREEN_LED_PIN_NAME      11
#define BLUE_LED_PIN_NAME       12
#define LED_PWM_FUNCTION        5
#define IOT_PWM_PORT_PWM1       1
#define IOT_PWM_PORT_PWM2       2
#define IOT_PWM_PORT_PWM3       3

#define OLED_I2C_BAUDRATE (400 * 1000)


static unsigned short int servport = 9002;
static char *servIP = "192.168.43.216";

static int sockfd = -1;
static int connfd = -1;
uint32_t retval = 0;
int key =1;



static void getStr(char msg[]){
        //环境
        float temp = 0.0, humi = 0.0;

        retval = AHT20_StartMeasure();
        printf("AHT20_StartMeasure: %u\r\n", retval);

        retval = AHT20_GetMeasureResult(&temp, &humi);
        // printf("AHT20_GetMeasureResult: %u, temp = %.2f, humi = %.2f\r\n",
        //        retval, temp, humi);

        sprintf(msg,"AHT20_GetMeasureResult: %u, temp = %.2f, humi = %.2f\r\n",retval, temp, humi);      


        // sleep(DELAY_S);


}

static void stateSend(char state[]){

                int ret = send(sockfd, state, strlen(state), 0);
                if (ret > 0) {
                    printf("%s: send: [%d] %s\n", __func__, ret, state);
                } else {
                printf("%s: send failed! client disconnect\n", __func__);
                        connfd = -1;
               }




}
 
 //指令判断
static void doSome(char want[]){

         unsigned char send_buff[64];
                if (strstr(want,"On"))
                {
                    if(strstr(want,"Light")){

                        for (int i = 1; i < IOT_PWM_PORT_PWM_MAX; i++) {
                            // use PWM control BLUE LED brightness
                            for (int j = 1; j <= IOT_PWM_DUTY_MAX; j *= NUM_2) {
                                IoTPwmStart(i, j, CLK_160M / PWM_FREQ_DIVITION);
                                usleep(DELAY_300MS);
                            }
                        }
                        stateSend("Light is on");
                    }
                    if(strstr(want,"Beep")){
                        IoTPwmStart(Beep_IOT_PWM_PORT_PWM0, PWM_DUTY_50, PWM_FREQ_4K);
                        stateSend("Beep is on"); 


                    }
                }
                

                if (strstr(want,"Off"))
                {
                    
                    if(strstr(want,"Light")){
                        for (int i = 1; i < IOT_PWM_PORT_PWM_MAX; i++) {
                            // use PWM control BLUE LED brightness
                            for (int j = 1; j <= IOT_PWM_DUTY_MAX; j *= NUM_2) {
                                usleep(DELAY_300MS);
                                IoTPwmStop(i);
                            }

                        }
                        stateSend("Light is Off");

                    }
                    if(strstr(want,"Beep")){

                        IoTPwmStop(Beep_IOT_PWM_PORT_PWM0);
                        stateSend("Beep is Off");


                    }
                }
                
                if(strstr(want,"Get")){

                    if(strstr(want,"Humi")){
                        getStr(send_buff);
                        stateSend(send_buff);
                    }
                }else{

                    stateSend("The instruction does not exist");
                }
                
                //指令判断


}



static void send2Serve(){

        int ret;
        unsigned char recv_buff[64] = { 0 };

                ssd1306_Fill(Black);
                ssd1306_SetCursor(0, 0);
                ssd1306_DrawString("开始测试", Font_7x10, White);

        while (1)
        {
            
       

        //TCP_S
        sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket

        struct sockaddr_in serverAddr = {0};
        serverAddr.sin_family = AF_INET;        // AF_INET表示IPv4协议
        serverAddr.sin_port = htons(servport);  // 端口号，从主机字节序转为网络字节序
        // 将主机IP地址从“点分十进制”字符串 转化为 标准格式（32位整数）

        if (inet_pton(AF_INET, servIP, &serverAddr.sin_addr) <= 0) {
            printf("%s: inet_pton failed!\n", __func__);
            close(sockfd);
            return;
        }

        // 尝试和目标主机建立连接，连接成功会返回0 ，失败返回 -1
        connfd = connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
        if (connfd != 0) {
            printf("%s: connect to server [%s][%d] failed!\n", __func__, servIP, servport);
            close(sockfd);
            sleep(1);
            continue;
        }

        printf("%s: connect to server [%s][%d] success!\n", __func__, servIP, servport);
        // 建立连接成功之后，这个TCP socket描述符 —— sockfd 就具有了 “连接状态”，
        // 发送、接收 对端都是 connect 参数指定的目标主机和端口

        while (connfd == 0) {

            
            sleep(DELAY_S);

            // ret = send(sockfd, send_buff, strlen(send_buff), 0);
            // if (ret > 0) {
            //     printf("%s: send: [%d] %s\n", __func__, ret, send_buff);
            // } else {
            //     printf("%s: send failed! client disconnect\n", __func__);
            //     connfd = -1;
            //     break;
            // }

            memset(recv_buff, 0, sizeof(recv_buff));
            ret = recv(sockfd, &recv_buff, sizeof(recv_buff), 0);
            if (ret > 0) {
                printf("%s: recv: [%d] %s\n", __func__, ret, recv_buff);

                ssd1306_Fill(Black);
                ssd1306_SetCursor(0, 0);
                ssd1306_DrawString(recv_buff, Font_7x10, White);
                ssd1306_UpdateScreen();

                doSome(recv_buff);
                printf("222222222");

            } else {
                printf("%s: recv failed! client disconnect\n", __func__);
                connfd = -1;
                break;
            }
           
        
        }

        }


}



void Aht20TestTask(void)
{

        //开环境
        retval = AHT20_Calibrate();
        printf("AHT20_Calibrate: %u\r\n", retval);

        
       

        hi_watchdog_disable();

        WifiTask();

        send2Serve();

    

}

static void initALL(void){

    //环境
    hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);
    hi_i2c_init(HI_I2C_IDX_0, I2C_DATA_RATE);
    
    //灯
	IoTGpioInit(RED_LED_PIN_NAME);
    IoTGpioInit(GREEN_LED_PIN_NAME);
    IoTGpioInit(BLUE_LED_PIN_NAME);

    // set Red/Green/Blue LED pin as output
    IoTGpioSetDir(RED_LED_PIN_NAME, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(GREEN_LED_PIN_NAME, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(BLUE_LED_PIN_NAME, IOT_GPIO_DIR_OUT);
	
	//灯pwm复用 
	// set Red/Green/Blue LED pin to pwm function
    hi_io_set_func(RED_LED_PIN_NAME, LED_PWM_FUNCTION);
    hi_io_set_func(GREEN_LED_PIN_NAME, LED_PWM_FUNCTION);
    hi_io_set_func(BLUE_LED_PIN_NAME, LED_PWM_FUNCTION);

    IoTPwmInit(IOT_PWM_PORT_PWM1); // R
    IoTPwmInit(IOT_PWM_PORT_PWM2); // G
    IoTPwmInit(IOT_PWM_PORT_PWM3); // B


    //Beer
    IoTGpioInit(Beep_GPIO_IDX_9);
    hi_io_set_func(Beep_GPIO_IDX_9, Beep_GPIO_PWM_FUNCTION);
    IoTGpioSetDir(Beep_GPIO_IDX_9, IOT_GPIO_DIR_OUT);
    IoTPwmInit(Beep_IOT_PWM_PORT_PWM0);

    //oled
    IoTI2cInit(0, OLED_I2C_BAUDRATE);
    ssd1306_Init();


}

void Aht20Test(void)
{
    osThreadAttr_t attr;
    initALL();
    attr.name = "Aht20Task";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = STACK_SIZE;
    attr.priority = osPriorityNormal;

    if (osThreadNew(Aht20TestTask, NULL, &attr) == NULL) {
        printf("[Aht20Test] Failed to create Aht20TestTask!\n");
    }
}
APP_FEATURE_INIT(Aht20Test);
